package requestctx

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"github.com/sirupsen/logrus"
	"strings"
	"sync"
)

type RequestHttp struct {
	ctx *gin.Context
	Params map[string]interface{}
	lock sync.Mutex
}

func Instance(ctx *gin.Context) *RequestHttp  {
	return &RequestHttp{
		ctx: ctx,
		Params: map[string]interface{}{},
	}
}

//获取默认参数列表
func (r *RequestHttp) GetDefaultParams() map[string]interface{} {
	ctx := r.ctx
	method := ctx.Request.Method
	url := ctx.Request.URL.Path
	return map[string]interface{}{
		"method": method,
		"url": url,
		"remoteAddr": r.GetRemoteAddr(),
		"params": r.RequestParams(),
		"requestID": r.GetHeaderByKey("request-id"),
		"status": ctx.Writer.Status(),
		"userAgent": ctx.GetHeader("User-Agent"),
	}
}

//获取kname
func (r *RequestHttp) GetHeaderByKey(kname string) string  {
	return r.ctx.Request.Header.Get(kname)
}

//获取remoteAddr
func (r *RequestHttp) GetRemoteAddr() string {
	remoteAddr := r.ctx.Request.Header.Get("Remote_addr")//远程调用
	if remoteAddr == "" {
		remoteAddr = r.ctx.Request.Header.Get("X-Forward-For")
	}
	return remoteAddr
}

//获取参数集合
func (r *RequestHttp) RequestParams() string {
	ctx := r.ctx
	bindParams := map[string]interface{}{}
	if ctx.Request.Method == "POST" || ctx.Request.Method == "PUT" {
		contextType := ctx.Request.Header.Get("Content-Type")
		if contextType == "application/json" {
			err := ctx.ShouldBindBodyWith(&bindParams, binding.JSON)
			if err != nil {//报错
				logrus.Errorf("nyx_request_mid_error %v,err: %v \n", bindParams, err)
				return ""
			}
			if len(bindParams) > 0 {
				for k, v :=  range bindParams {
					r.Add(k, v)
				}
			}
		} else {
			_ = ctx.Request.ParseMultipartForm(32 << 20)
			if len(ctx.Request.PostForm) > 0 {
				for k, v := range ctx.Request.PostForm {
					r.Add(k, v[0])
				}
			}
		}
	} else {
		var tmpParams = make(map[string]string)
		err2 := ctx.ShouldBind(&tmpParams)
		if err2 != nil {
			fmt.Println(err2)
			logrus.Errorf("nyx_request_mid_error %v,err: %v \n", bindParams, err2)
			return ""
		}
		for k, v := range tmpParams {
			r.Add(k, v)
		}
	}
	return r.JoinParamsStr()
}

//添加参数
func (r *RequestHttp) AddParams(m map[string]interface{})  {
	if len(m) <= 0 {
		return
	}
	for k, v :=  range m {
		r.Add(k, v)
	}
}

func (r *RequestHttp) JoinParamsStr() string {
	var params []string
	if len(r.Params) > 0 {
		for k,v := range r.Params {
			params = append(params, fmt.Sprintf("%s=%v", k, v))
		}
	}

	return strings.Join(params, "&")
}

//添加参数
func (r *RequestHttp) Add(key string, value interface{})  {
	r.lock.Lock()
	r.Params[key] = value
	r.lock.Unlock()
}

//删除参数
func (r *RequestHttp) Delete(key string)  {
	r.lock.Lock()
	if _,ok := r.Params[key]; ok {
		delete(r.Params, key)
	}
	r.lock.Unlock()
}